#include "Subsystems/BlockBehaviors/SubsystemRakeBlockBehavior.h"
#include "Log.h"
#include "GameSingleton.h"
#include "Components/ComponentMiner.h"
#include "Subsystems/SubsystemTerrain.h"

#include "Blocks/DirtBlock.h"
#include "Blocks/GrassBlock.h"
#include "Blocks/SoilBlock.h"

#include "Blocks/IronRakeBlock.h"
#include "Blocks/CopperRakeBlock.h"
#include "Blocks/WoodenRakeBlock.h"
#include "Blocks/DiamondRakeBlock.h"


namespace PocketSurvival
{

    SubsystemRakeBlockBehavior::SubsystemRakeBlockBehavior()
    {
        m_handleBlocks.push_back(IronRakeBlock::Index());
        m_handleBlocks.push_back(CopperRakeBlock::Index());
        m_handleBlocks.push_back(WoodenRakeBlock::Index());
        m_handleBlocks.push_back(DiamondRakeBlock::Index());
    }

    bool SubsystemRakeBlockBehavior::onUse(const Ray3 &ray, ComponentMiner *componentMiner)
    {
        RaycastData raycastData = componentMiner->raycast(ray, RaycastMode::Interaction);
        if(raycastData.terrainRaycastResult != nullptr)
        {
            if(raycastData.terrainRaycastResult->cellFace.face == 4)
            {
                Point3 &point = raycastData.terrainRaycastResult->cellFace.point;
				int32_t cellValue = m_terrain->getCellValue(point);
				int32_t cellContents = Terrain::ExtractContents(cellValue);
				Block *block = GameSingleton::blocksManager->blocks[cellContents];
                int32_t value2;
                switch (cellContents)
                {
                case DirtBlock::Index():        // 泥土
                    value2 = Terrain::ReplaceContents(cellValue, SoilBlock::Index());   // 转耕地
                    m_terrain->changeOldCell(point, cellValue, value2);
                    break;
                case GrassBlock::Index():       // 草地
                    value2 = Terrain::ReplaceContents(cellValue, DirtBlock::Index());   // 转泥土
                    m_terrain->changeOldCell(point, cellValue, value2);
                    break;
                }
            }
            componentMiner->damageActiveTool(1);
        }
        return false;
    }

    void SubsystemRakeBlockBehavior::load(const nlohmann::json &json)
    {
        m_terrain = GameSingleton::singletonPtr->getSingleton<SubsystemTerrain>();
    }

    static const std::string subsystemName = "RakeBlockBehavior";
    const std::string& SubsystemRakeBlockBehavior::getName() const
    {
        return subsystemName;
    }

}